#lang scheme


(define // quotient)
(define % remainder)

; Передаём lst и список от 1 до len(lst)
; И создаём  список из пар '( (lst . id) ... )
(define (z1_1 lst)
  (map (λ (lst id) (cons lst id))
       lst
       (build-list (length lst) add1)))

; Используя filter, сохраняем те элементы из списка пар, для которых lst mod id = 0
(define (z1_2 lst)
  (filter (λ (pr) (= 0 (% (car pr) (cdr pr)))) (z1_1 lst)))

; Отбрасываем все нетрехзначные числа, сохраняя в список(*)
; Применяем apply + к списку(*), вычисляя сумму его элементов
(define (z2 lst)
  (apply + (filter (λ (x) (and (< (abs x) 1000) (> (abs x) 99))) lst)))

; Пробегаясь по двум спискам, применяем элемент из operations к результату и элементу из numbers
(define (z3 numbers operations)
  (foldl (λ (oper num res) (if (and (equal? / (eval oper)) (= num 0))
                               #f
                               ((eval oper) res num))) (car numbers) operations (cdr numbers)))

; Делаем len(lst) шагов
; Каждый шаг добавляем к res список lst, у которого убраны len(res) первых элементов
; (1 2 3 4) -> (2 3 4) -> (3 4) -> (4)
(define (z4 lst)
  (reverse (foldl (λ (_ res) (cons (drop lst (length res)) res)) '() lst)))


(define (z5 sum r operations) ; sum - нач. состояние банковского счёта, r - процентная ставка, operations - ежедневные операции
  (define R (+ 1 (/ r 100)))  ; коэффицент пополнения
  (define days-with-oper (map (λ (oper) (car oper)) operations)) ; находим список из дней, в которые были произведены операции
  (define (day-sum sum day)   ; состояние счёта на конец дня day
    (* R (foldl (λ (oper sum)
                  ((eval (cadr oper)) sum (caddr oper))) ; вычисляем состояние счёта после операции
                sum (filter (λ (oper) (= (car oper) day)) operations)))) ; передаем сумму и список операций в день day
  (foldl (λ (day sum) ; пробегаемся по дням и добавляем к сумме начисление за день day
           (if (member day days-with-oper) ; включает в себя дни с операциями текущий день
               (day-sum sum day)           ; то добавляем к сумме начисления
               (* sum R)))                 ; начисляем процент
         sum (build-list (- 31 (caar operations)) (λ(x)(+ (caar operations) x))))) ; передаем сумму, список из дней


